home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Tele / P / Periscope folder / pscopeunix.c < prev   
Encoding:
C/C++ Source or Header  |  1992-04-16  |  7.0 KB  |  319 lines  |  [TEXT/MPS ]

  1. /*  pscope (periscope) allows a macintosh connected to the network to
  2.     "see" into a unix directory and retrieve files from it         */
  3.  
  4. #include    <sys/types.h>
  5. #include    <sys/socket.h>
  6. #include    <sys/time.h>
  7. #include    <netinet/in.h>
  8. #include    <netdb.h>
  9. #include    <stdio.h>
  10. #include <errno.h>
  11. #include <sys/stat.h>
  12. #include <pwd.h>
  13.  
  14. #define TRUE 1
  15. #define SEND 0
  16. #define RECEIVE 1
  17. #define MORE 0
  18. #define DONE 1
  19. #define kTCPBlockSize 256
  20. #define HANDSHAKE 2
  21. #define PROTOCOL_ERR 2
  22. #define TERMINATING 3
  23. #define BAD_NAME 4
  24.  
  25. int inDescriptor;
  26. struct stat inStat;
  27. int inSize;
  28. FILE *in = stdin,*out = stdout;
  29. unsigned char *outbuf = NULL;        /* file buffer -> mac */
  30.  
  31. void handshake(buf,bytes,sock)
  32. char *buf;
  33. int bytes;
  34. int sock;
  35. {
  36.   char *username;
  37.   struct passwd *userinfo;
  38.  
  39.   unsigned char controlByte = buf[0];
  40.  
  41.   outbuf = (unsigned char *)malloc(1);
  42.  
  43.   if(controlByte != HANDSHAKE){
  44.     /* protocol error */
  45.     outbuf[0] = PROTOCOL_ERR;
  46. #ifdef DEBUG
  47.     fprintf(stderr,"Bad Handshake\n");
  48. #endif
  49.     if(write(sock,outbuf,1) < 0)
  50.     perror("ERROR writing to socket");
  51.     outbuf[0] = TERMINATING;
  52.     if(write(sock,outbuf,1) < 0)
  53.     perror("ERROR writing to socket");
  54.     close(sock);
  55.     exit(0);
  56.   }
  57.   
  58.   /* rest of message is userid */
  59.   username = (char *)malloc(bytes);
  60.   memcpy(username,&buf[1],bytes-1);
  61.   username[bytes-1] = '\0';
  62.   userinfo = getpwuid(getuid());
  63.   if(strcmp(username,userinfo->pw_name)){
  64.     /* account names don't match */
  65.     outbuf[0] = BAD_NAME;
  66. #ifdef DEBUG
  67.     fprintf(stderr,"Bad Account\n");
  68. #endif
  69.     if(write(sock,outbuf,1) < 0)
  70.       perror("ERROR writing to socket");
  71.     outbuf[0] = TERMINATING;
  72.     if(write(sock,outbuf,1) < 0)
  73.       perror("ERROR writing to socket");
  74.     close(sock);
  75.     free(userinfo);
  76.     exit(0);
  77.   }
  78.   
  79.   /* Don't worry, be happy! */
  80.   free(userinfo);
  81.   outbuf[0] = 0;
  82.   if(write(sock,outbuf,1) < 0)
  83.     perror("ERROR writing to socket");
  84.   return;
  85. }
  86.  
  87. void handleMessage(buf,size,msgsock)
  88. char *buf;
  89. int size;
  90. int msgsock;
  91. {
  92.   unsigned char controlByte;
  93.   int nBytes;
  94.   char *data;
  95.   char *filename;
  96.   int bytesSent = 0;
  97.   int bytesToGo;
  98.   int sendBytes;
  99.   controlByte = buf[0];
  100.  
  101.   switch(controlByte){
  102.   case SEND:
  103.     /* client wants server to send data, resulting from last request */
  104.  
  105.     /* allocate enough buffer space to transmit at least an error */
  106.     outbuf = (unsigned char *)malloc(1);
  107.  
  108.     memcpy(&nBytes,&(buf[1]),sizeof(int)); /* no of bytes in file name */
  109.     filename = (char *)malloc(nBytes+1);
  110.     memcpy(filename,&(buf[5]),nBytes);    /* got the filename assigned */
  111.     filename[nBytes] = '\0';              /* termninate fname string */
  112.  
  113.     /* set error flag */
  114.     outbuf[0] = 1;
  115.     
  116.     if((inDescriptor = open(filename,0)) == -1){
  117. #ifdef DEBUG
  118.       fprintf(stderr,"failed to open %s\n",filename);
  119. #endif
  120.       if(write(msgsock,outbuf,1) < 0)
  121.     perror("ERROR writing to socket");
  122.       break;
  123.     }
  124.     free(filename);
  125.     /* get input file info */
  126.  
  127.     fstat(inDescriptor,&inStat);
  128.     inSize = inStat.st_size;
  129.  
  130.     /* dynamically allocate enough buffer space here */
  131.     outbuf = (unsigned char *)realloc(outbuf,inSize+4+1);
  132.     /* write number of bytes in data to buffer */
  133.     memcpy(&outbuf[1],&inSize,sizeof(inSize));
  134.  
  135.     nBytes = read(inDescriptor,&(outbuf[5]),inSize);
  136.  
  137. #ifdef DEBUG
  138.     fprintf(stderr,"read %d bytes\n",nBytes);
  139. #endif
  140.  
  141.     if(nBytes < 0){
  142. #ifdef DEBUG
  143.       fprintf(stderr,"read error: %d\n",errno);
  144. #endif      
  145.       if(write(msgsock,outbuf,1) < 0)
  146.     perror("ERROR writing to socket");
  147.       break;
  148.     }
  149.     else if (nBytes == 0){
  150. #ifdef DEBUG
  151.       fprintf(stderr,"No data read\n");
  152. #endif
  153.       if(write(msgsock,outbuf,1) < 0)
  154.     perror("ERROR writing to socket");
  155.       break;
  156.     }
  157.  
  158.     outbuf[0] = 0;                /* data is good */
  159.     /* send control byte + size int */
  160.     if(write(msgsock,outbuf,5) < 0)
  161.       perror("ERROR writing to socket");
  162.     if(write(msgsock,&(outbuf[5]),inSize) < 0)
  163.       perror("ERROR writing to socket");
  164.  
  165.     break;
  166.  
  167.   case RECEIVE:
  168.     /* client wants to send data to the server */
  169.     memcpy(&nBytes,&(buf[1]),sizeof(int));
  170.     fprintf(stderr,"RECEIVE\n");
  171.     fflush(stderr);
  172.     ntohs(nBytes);
  173.     fprintf(stderr,"nBytes = %d\n",nBytes);
  174.     fprintf(stderr,"%d\n%d\n%d\n%d\n",buf[1],buf[2],buf[3],buf[4]);
  175.     data = (char *)malloc((nBytes + 1) * sizeof(char));
  176.     memcpy(data,&(buf[1+sizeof(int)]),nBytes);
  177.     data[nBytes] = '\0';
  178.     fprintf(out,"-->%s\n",data);
  179.     free(data);
  180.     break;
  181.  
  182.   default:
  183.     break;
  184.   }
  185. }
  186.     
  187. main(argc,argv)
  188. int argc;
  189. char **argv;
  190. {
  191.  
  192.   int port = 32200;
  193.   int sock , range = 10, length;
  194.   struct sockaddr_in server;
  195.   int msgsock;
  196.   char buf[1024];
  197.   int rval;
  198.   fd_set ready;
  199.   struct timeval to;
  200.   char *filename;
  201.   extern char *optarg;
  202.   int nonOptArgs;
  203.   char c;
  204.   int p_flag = 0;
  205.   int r_flag = 0;
  206.   int done = 0;
  207.   int result;
  208.  
  209.   /* process command line args */
  210.   while((c = getopt(argc,argv,"p:r:")) != -1)
  211.     switch(c){
  212.     case 'p':
  213.       p_flag = 1;
  214.       port = atoi(optarg);
  215.       break;
  216.     case 'r':
  217.       r_flag = 1;
  218.       range = atoi(optarg);
  219.       break;
  220.     default:
  221. #ifdef DEBUG
  222.       fprintf("improper option ignored\n");
  223. #endif
  224.       ;
  225.     }
  226.  
  227.   nonOptArgs = argc - 1 - p_flag - r_flag;
  228.  
  229.   /* Create Socket */
  230.  
  231.   sock = socket(AF_INET, SOCK_STREAM, 0);
  232.   if (sock < 0)
  233.     {
  234.       perror("ERROR opening stream socket");
  235.       exit(1);
  236.     }
  237.   
  238.   /* Name socket using wilddcards */
  239.   
  240.   server.sin_family = AF_INET;
  241.   server.sin_addr.s_addr = INADDR_ANY;
  242.   server.sin_port = port;
  243.   /* search until unused port# is found or range exhausted */
  244.   while(!done && server.sin_port < (port + range)){
  245.     result = bind(sock, (struct sockaddr *)&server,
  246.        sizeof server);
  247.     if(result < 0)
  248.       server.sin_port++;
  249.     else
  250.       done = 1;
  251.   }
  252.   if(!done){
  253.     fprintf(stderr,"Unable to bind socket to port, exitting...\n");
  254.     exit(1);
  255.   }
  256. #ifdef DEBUG
  257.   fprintf(stderr,"Socket prot #%d\n", ntohs(server.sin_port));
  258. #endif
  259.   
  260.   /* Start accepting connections */
  261.   
  262.   listen(sock, 5);
  263.   do
  264.     {
  265.       FD_ZERO(&ready);
  266.       FD_SET(sock, &ready);
  267.       to.tv_sec = 5;
  268.       if (select(sock + 1, &ready, (fd_set *)0,
  269.          (fd_set *)0, &to) < 0)
  270.     {
  271.       perror("ERROR select");
  272.       continue;
  273.     }
  274.       if (FD_ISSET(sock, &ready))
  275.     {
  276.       msgsock = accept(sock, (struct sockaddr *)0,
  277.                (int *)0);
  278.       if (msgsock == -1) perror("ERROR accept");
  279.       else {
  280.         if(fork() == 0){ /* child */
  281.           close(sock);
  282.  
  283.           /* do the handshake */
  284.           bzero(buf,sizeof buf);
  285.           if ((rval = read(msgsock, buf, 1024)) < 0) {
  286.         perror("ERROR reading stream message");
  287.         close(msgsock);
  288.         exit(0);    /* child dies */
  289.           }          
  290.           if(rval == 0){
  291.         close(msgsock);
  292.         exit(0);
  293.           }
  294.           handshake(buf,rval,msgsock);
  295.  
  296.           do
  297.         {
  298.           bzero(buf, sizeof buf);
  299.           /* block until data is available */
  300.           if ((rval = read(msgsock, buf, 1024)) < 0) {
  301.             perror("ERROR reading stream message");
  302.             close(msgsock);
  303.             exit(0);    /* child dies */
  304.           }
  305.           else if (rval == 0) 
  306.             printf("No more data\n");
  307.           else
  308.             handleMessage(buf,1024,msgsock);
  309.         }
  310.           while(rval > 0);
  311.         }
  312.         close(msgsock); /* parent */
  313.       }
  314.     }
  315.     }
  316.   while(TRUE);
  317.   exit(0);
  318. }
  319.